package cloudspace.vm.javassist;

import java.util.List;

import javassist.CannotCompileException;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.NotFoundException;
import javassist.expr.Expr;

import org.apache.log4j.Logger;

import cloudspace.vm.VM;
import cloudspace.vm.javassist.AbstractCommand.SignatureType;


/**
 * This command adds a method to a Class. It is defined by the following
 * configuration line.
 * 
 * translate AddMethod <Class Name> <Return Type> <Method Name> <Parameter type>
 * <Method Body>
 * 
 * The class name is the fully defined name of the class to add the method to.
 * It can be a super class. The return type is the return type for the method.
 * The method name is the simple name designating the method. The parameter type
 * is the parameter type for the first parameter, the current implementation
 * only supports one parameter methods. The method body is the body of the
 * method to be added, it supports the use of macros.
 * 
 * @author Mike Woods
 * 
 */
public class AddMethod implements CommandInterface
{
    private Logger logger = Logger.getLogger( AddMethod.class );

    private List<String> configArgs;


    public AddMethod( List<String> args )
    {
        configArgs = args;
    }


    public String getReplacement()
    {
        // TODO Auto-generated method stub
        return configArgs.get( 5 ).substring( 1,
            configArgs.get( 5 ).length() - 1 );
    }


    public String getSignature()
    {
        return configArgs.get( 1 );
    }


    public SignatureType getSignatureType()
    {
        return SignatureType.STATICDEFINITION;
    }


    public void translate( Expr call, boolean isSuper )
        throws MalformedCommandException,
        CannotCompileException
    {
        throw new MalformedCommandException( "This command is not implemented" );

    }


    public void translate( CtMethod member, String expressionName )
        throws MalformedCommandException,
        CannotCompileException,
        MalformedCommandException
    {
        throw new MalformedCommandException( "This command is not implemented" );
        // member.addLocalVariable(name, type);

    }


    public void translate( CtClass clazz )
        throws MalformedCommandException,
        CannotCompileException
    {

        try
        {
            CtClass superClazz = clazz.getSuperclass();
            while ( superClazz != null )
            {
                if ( superClazz.getName().equals( getSignature() ) )
                {
                    // CtClass returnClazz =
                    // VM.identifyCurrentVM().getClassPool().get(configArgs.get(2));
                    CtClass param = VM.currentVM()
                        .getClassPool()
                        .get( configArgs.get( 4 ) );
                    CtMethod methodToAdd = new CtMethod( CtClass.voidType,
                        configArgs.get( 3 ),
                        new CtClass[] { param },
                        clazz );
                    String replacement = getReplacement();
                    methodToAdd.setBody( replacement );
                    clazz.addMethod( methodToAdd );
                }
                superClazz = superClazz.getSuperclass();
            }
        }
        catch ( NotFoundException e )
        {
            logger.error( "Class not found for Add Method Translation:  "
                + clazz.getName(), e );
            ;
        }

    }

}
